<?php
/**
 * 
 * @author: peng.shan <peng.shan@happyelements.com>
 * @version $Id: Sso.php 275346 2012-12-14 08:13:18Z peng.shan $
 */
class Sso{
    
    const NEED_IP_CHECK=0;
    private $appid;
    private $key;
    public  $callback_url;
    public $sso_url;
    function __construct($env ='' ,$lang ='en'){
        $this->appid="expense";
        $this->key= "0c80b59d5948056a5927937836b8043f";
      //$this->callback_url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['PORT']."/sys".$env."/".$lang."/classic/login/sysLoginSSOVerify";
	//   $this->callback_url = 'http://10.130.132.240/expense/';
        $this->callback_url = Yii::app()->params['siteUrl'];
      ///sys_hec/en/classic/login/sysLoginVerify
        $this->sso_url="https://mail.happyelements.com:4432/";
    }
    
    function reset_callback_url($url){
        $this->callback_url=$url;
    }

    function des_decrypt($ekey,$b64){
        $key =pack("H*", substr($ekey,0,16));
        $iv = pack("H*", substr($ekey,16,16));
        $enc =  base64_decode($b64);
        $dec = mcrypt_decrypt(MCRYPT_DES, $key,$enc,MCRYPT_MODE_CBC ,$iv);
        //remove pkcs padding!
        $dec_s = strlen($dec);
        $pad= ord($dec[$dec_s-1]); 
        $dec = substr($dec, 0, -$pad);
        return $dec;
    }
    function des_encrypt($ekey,$dec){
        //add pkcs padding
        $blocksize= 8;
        $pad = $blocksize - (strlen($dec) % $blocksize);
        $dec .= str_repeat(chr($pad), $pad);
        $key =pack("H*", substr($ekey,0,16));
        $iv = pack("H*", substr($ekey,16,16));
        $enc = mcrypt_encrypt(MCRYPT_DES, $key,$dec,MCRYPT_MODE_CBC ,$iv);
        return base64_encode($enc);
    }

    function des_encrypt_hash($ekey,$dec){
        $dec = pack("H*",md5($dec)).$dec;
        return  $this->des_encrypt($ekey,$dec);
    }

    function des_decrypt_hash($ekey,$enc){
        $dec = $this->des_decrypt($ekey,$enc);
        $src = substr($dec,16);
            $m = md5($src);
            $h = substr($dec,0,16);
        if($m!=bin2hex($h)) return null;
        return $src;
    }

    function get_ip(){
        $unknown = 'unknown';
        if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'],$unknown)){
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        }elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'],$unknown)){
            $ip = $_SERVER['REMOTE_ADDR'];
        } /* 处理多层代理的情况 或者使用正则方式：$ip = preg_match("/[\d\.]{7,15}/", $ip, $matches) ? $matches[0] : $unknown; */
        if(false !== strpos($ip, ','))
        $ip = reset(explode(',', $ip));
        return $ip;
    }
    
    function check_ip($ip){
        if(!SSO::NEED_IP_CHECK) return true;
        else return $ip == $this->get_ip();
    }

    function get_sso_url($logoff=false,$returnurl=''){
        $ip = $this->get_ip();
        if($returnurl=='') $this->callback_url = Yii::app()->params['siteUrl'];
        else $this->callback_url = $returnurl;
        $token = time().",".$ip.",".$this->callback_url;
        $enctoken = $this->des_encrypt_hash($this->key,$token);
        $this->sso_url .=  "?appid=".$this->appid."&reqtoken=".urlencode($enctoken);
        if($logoff) $this->sso_url.="&logoff=true";
        return $this->sso_url;
    }

    function parse_sso_response_token($rsptoken=null){
		$_GET["rsptoken"] = isset($_GET["rsptoken"]) ? $_GET["rsptoken"] : null;
        if(!$rsptoken) $rsptoken = $_GET["rsptoken"];
        $token = $this->des_decrypt_hash($this->key,$rsptoken);
        //echo 'token='.$token;
        if(!$token) return null;
        $ss = explode(",",$token);
        if(count($ss)<3) return null;
        $time = (int) $ss[0];
        $ip = $ss[1];
        $user = $ss[2];
        if(time() -  $time>600) return null;//ignore
        if(!$this->check_ip($ip))return null;
        return $user;
    }
}